﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Comm.PublicClass;
using WsProtocol.PublicClass;

namespace Wasion.HHU.Services
{
    public class FunMeterBase
    {
        public delegate void DoAfterListen(object testMeter, object anaPtl, int doflag, string errinfo);  //监听数据处理完之后的委托
        
        protected bool stopreading = false;  //主动终止通信过程
        public List<PtlBaseMeter> BaseMeterLst = new List<PtlBaseMeter>();  //当前操作的电表对象
        private List<CommConst.TOrdertype> ListenOrderlst = new List<CommConst.TOrdertype>();  //当前监听指令对象
        private DoAfterListen doAfterListen = null;
        public bool CheckConnect = false;  //是否需要检查连接  主要针对蓝牙通信

        //属性
        /// <summary>
        /// 是否停止与表通信
        /// </summary>
        /// <param name="ifstop"></param>
        public void StopOperating(bool ifstop)
        {
            stopreading = ifstop;
            string errinfo = string.Empty;
            if (stopreading)
            {
                for (int i = 0; i < BaseMeterLst.Count; i++)
                {
                    if (BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.威胜蓝牙)
                    {
                        //CommManager.StopOrder(CommProperty.CommMode.RS232, BaseMeterLst[i].CommInfo.CommName, ref errinfo);
                    }
                }

            }
        }


        #region 公用函数



        #endregion
        /// <summary>
        /// 保存某表位的波特率
        /// </summary>
        /// <param name="ameter"></param>
        //public void SaveBaudRate(int sno, int newBaudRate, ref string errinfo)
        //{
        //    TCommProperty commpro = TCommProperty.GetCommProperty(sno, ref errinfo);
        //    if (commpro != null)
        //        commpro.SaveBaudRate(sno, newBaudRate);            
        //}

        /// <summary>
        /// 关闭串口或断开TCP连接
        /// </summary>
        /// <param name="BaseMeterLst"></param>
        //public void CloseComm()
        //{
        //    for (int i = 0; i < BaseMeterLst.Count; i++)    
        //    {
        //        Application.DoEvents();
        //        string errinfo = string.Empty;

        //        int rs = 0;
        //        if (BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.串口485 
        //            || BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.光口通信
        //            //|| BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.低功耗蓝牙
        //            || BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.威胜蓝牙)
        //            rs = CommManager.CloseComm(Comm.BottomComm.CommProperty.CommMode.RS232, BaseMeterLst[i].CommInfo.CommName, ref errinfo);
        //        else
        //            if (BaseMeterLst[i].CommInfo.ConnMode == SourceMeterMode.TCP直连)
        //                rs = CommManager.CloseComm(Comm.BottomComm.CommProperty.CommMode.TCPC, BaseMeterLst[i].SNO.ToString(), ref errinfo);

        //        if (rs < 0)
        //            BaseMeterLst[i].ErrInfo = errinfo;
        //    }

        //}

        

        

        /// <summary>
        /// 向通信信息发送消息，提示不支持读或写的命令
        /// </summary>
        /// <param name="ordername"></param>
        public void NoOrderMessage(string ordername)
        {
            //CommConst.TOrdertype nextOrder = new CommConst.TOrdertype();
            //nextOrder.MeterSNo = 0;
            //nextOrder.OrderName = ordername;
            //nextOrder.errorinfo = ordername;
            //nextOrder.SendFlag = CommConst.CommFlag.CommSendFail;
            //nextOrder.Msgflag = CommConst.CommFlag.CommSendFail;
            //if (PtlBaseUIProConsts.ShowComminfo != null)
            //    PtlBaseUIProConsts.ShowComminfo(nextOrder);
        }


        /// <summary>
        /// 发送指令并等待处理完毕
        /// </summary>
        /// <param name="OrderLst"></param>
        public void SendAndWait(List<CommConst.TOrdertype> orderlst)
        {
            if (orderlst == null || orderlst.Count == 0)
                return;
            int orderwait = 5000;   //指令超时时间
            #region 添加指令部分
            List<CommConst.TOrdertype> HWorderlst = new List<CommConst.TOrdertype>();  //通过硬件发送给表的指令
            for (int i = 0; i < orderlst.Count; i++)
            {
                //Application.DoEvents();
                if (stopreading)
                    return;
                CommConst.TOrdertype neworder = orderlst[i];
                neworder.DoChangeStatus += PtlBaseUIProConsts.ShowComminfo;//new CommConst.EventChangeStatus(PtlBaseUIProConsts.ShowComminfo); //绑定界面显示收发帧事件
                neworder.DoAnalysis = PtlBaseUIProConsts.doAnalysis; 

                //指定通信方式和串口
                int rs = TCommProperty.SetConnMode(neworder);
                if (rs < 0)
                {
                    neworder.Fail(false, "");
                    continue;
                }
                string errinfo = string.Empty;
                TCommProperty commpro = TCommProperty.GetCommProperty(neworder.MeterSNo, ref errinfo);

                PtlBaseMeter meterobj = (PtlBaseMeter)neworder.meterObj;
                meterobj.CommInfo.SNO = neworder.MeterSNo;
                meterobj.CommInfo.ConnMode = SourceMeterMode.串口485;
                meterobj.CommInfo.CommName = "串口485";

                try
                {
                    errinfo = string.Empty;
                    
                    //if (commpro.ConnMode == SourceMeterMode.威胜蓝牙)  //蓝牙模块每次会去判断是否要重建连接
                    //{
                    //    neworder.ResetComm = CheckConnect;
                    //    CheckConnect = false;
                    //}

                    try
                    {
                        neworder.Msgflag = CommConst.CommFlag.CommSending;
                        neworder.SendFlag = CommConst.CommFlag.CommSending;
                        var testMeter = ((TestMeter)neworder.meterObj);
                        //testMeter.currorder = neworder;
                        testMeter._meter.WriteAsync(neworder.order);
                    }
                    catch (Exception ex)
                    {
                        errinfo = ex.Message;
                        rs = -1;
                    }
                    if (rs <= 0)
                    {
                        neworder.Fail(false, errinfo);
                        continue;
                    }

                    //rs = CommManager.AddOrder(neworder, ref orderwait, ref errinfo);
                    //if (rs <= 0)
                    //{
                    //    neworder.Fail(false, errinfo);
                    //    continue;
                    //}

                }
                catch (Exception ex)
                {
                    neworder.Fail(false, "add order error:" + ex);
                    continue;
                }
            }

            //有通过硬件抄表的指令，启动硬件的发指令过程
            if (HWorderlst.Count > 0)
            {
                //string errinfo = string.Empty;
                //int rs = HardwareManager.StartOrderToMeter(ref errinfo);
                //if (rs < 0)
                //{
                //    for (int i = 0; i < HWorderlst.Count; i++)
                //        HWorderlst[i].Fail(false, errinfo);
                //}
            }


            #endregion

            #region 等待发送和解析完毕
            int waittime = 0;            
            bool orderdoing = false;
            for (int i = 0; i < orderlst.Count; i++) 
            {
                //Application.DoEvents();
                orderdoing = !orderlst[i].OrderDone;
                if (orderdoing)
                    break;
            }

            int maxwaittime = orderlst.Count * orderwait * 5;   //最大等待时间 
            if (BaseMeterLst.Count > 0)
                maxwaittime *= BaseMeterLst.Count;

            DateTime outtime = DateTime.Now.AddMilliseconds(maxwaittime);
            while (!stopreading && orderdoing)
            {
                //Application.DoEvents();
                //Thread.Sleep(2);
                Task.Delay(2).Wait();
                if (outtime <= DateTime.Now)
                {
                    for (int i = 0; i < orderlst.Count; i++)
                    {
                        if (orderlst[i].continueorder != string.Empty || orderlst[i].SendFlag == CommConst.CommFlag.CommReceived) //有续抄指令 继续等待
                        {
                            outtime = DateTime.Now.AddMilliseconds(maxwaittime);
                            continue;
                        }
                        else
                        {
                            if (orderlst[i].SendFlag == CommConst.CommFlag.CommNone)
                            {
                                orderlst[i].Fail(false, "order undo");
                            }
                            else
                                if (orderlst[i].SendFlag == CommConst.CommFlag.CommSending)
                                {
                                    orderlst[i].Fail(false, "order sending");
                                }
                                else
                                    orderlst[i].Fail(false, "other error");
                        }

                    }
                    if (waittime > 0)
                        break;
                }
                orderdoing = false;
                for (int i = 0; i < orderlst.Count; i++)
                {
                    //Application.DoEvents();

                    orderdoing = !orderlst[i].OrderDone;
                    if (orderdoing)
                        break;
                }
            }
            #endregion

        }


        /// <summary>
        /// 启动监听服务，用于处理主动上传
        /// </summary>
        /// <param name="meterSNo">表位</param>
        /// <param name="doAfterReceive">收到返回后的处理委托</param>
        //public void StartListen(List<CommConst.TOrdertype> orderlst, DoAfterListen afterlisten)
        //{
        //    if (orderlst == null || orderlst.Count == 0)
        //        return;
        //    ListenOrderlst = orderlst;
        //    doAfterListen = afterlisten;
        //    for (int i = 0; i < orderlst.Count; i++)
        //    {
        //        CommConst.TOrdertype neworder = orderlst[i];
        //        string errinfo = string.Empty;
        //        neworder.DoChangeStatus += PtlBaseUIProConsts.ShowComminfo;
        //        neworder.DoAfterReceive = DoFromListen; //绑定收到数据处理委托

        //        //指定通信方式和串口
        //        int rs = TCommProperty.SetConnMode(neworder);
        //        if (rs < 0)
        //        {
        //            neworder.Fail(false, "");
        //            continue;
        //        }

        //        TCommProperty commpro = TCommProperty.GetCommProperty(neworder.MeterSNo, ref errinfo);

        //        PtlBaseMeter meterobj = (PtlBaseMeter)neworder.meterObj;
        //        meterobj.CommInfo.SNO = neworder.MeterSNo;
        //        meterobj.CommInfo.ConnMode = commpro.ConnMode;
        //        meterobj.CommInfo.CommName = commpro.CommName;


        //        try
        //        {
        //            errinfo = string.Empty;
        //            switch (commpro.ConnMode) 
        //            {
        //                case SourceMeterMode.TCP直连:
        //                case SourceMeterMode.UDP直连:                        
        //                case SourceMeterMode.威胜蓝牙:
        //                    if (commpro.ConnMode == SourceMeterMode.TCP直连 || commpro.ConnMode == SourceMeterMode.UDP直连)
        //                    {
        //                        //表对象的IP和端口传给指令对象
        //                        try
        //                        {
        //                            string[] addr = meterobj.IPAndPort.Split(':');
        //                            neworder.peerip = addr[0];
        //                            neworder.peerport = int.Parse(addr[1]);
        //                        }
        //                        catch (Exception ex)
        //                        {
        //                            neworder.Fail(false, "ip and port error:" + ex.Message);
        //                            continue;
        //                        }
        //                    }
        //                    else
        //                        if (commpro.ConnMode == SourceMeterMode.威胜蓝牙)  //蓝牙模块每次会去判断是否要重建连接
        //                        {
        //                            neworder.ResetComm = true;
        //                        }
        //                    break;
        //            }

        //        }
        //        catch (Exception ex)
        //        {

        //        }

        //        rs = CommManager.StartListen(orderlst[i], ref errinfo);
        //        if (rs < 0)
        //        {
        //            orderlst[i].Fail(false, errinfo);
        //            meterobj.ErrInfo = errinfo;
        //            if (afterlisten != null)
        //                afterlisten(meterobj, neworder.AnaPtl, -1, errinfo);
        //        }
        //    }
        //}


        /// <summary>
        /// 将收到的数据放到缓冲区  shaunwang  2019-8-19  
        /// </summary>
        /// <param name="arecstr"></param>
        //private void DoFromListen(string commname, ref string arecstr)
        //{
        //    if (string.IsNullOrEmpty(arecstr) || PtlBaseUIProConsts.doAnalysis == null)
        //        return;
        //    try
        //    {
        //        string rstr = arecstr;
        //        for (int i = 0; i < ListenOrderlst.Count; i++)
        //        {
        //            if (ListenOrderlst[i].commname.ToUpper() == commname.ToUpper())
        //            {
        //                ListenOrderlst[i].errorinfo = string.Empty;  //重置错误信息
        //                ListenOrderlst[i].recstr = rstr;
        //                ListenOrderlst[i].Msgflag = CommConst.CommFlag.CommReceived;
        //                ListenOrderlst[i].SendFlag = CommConst.CommFlag.CommReceived;
                        
        //                PtlBaseUIProConsts.doAnalysis(ListenOrderlst[i]);  //解析返回帧  顺便看看是不是主动上报的                      
        //                PtlBase anaptl = (PtlBase)ListenOrderlst[i].AnaPtl;

        //                string realdata = anaptl.GetRealData();
        //                if (!string.IsNullOrEmpty(realdata))
        //                    ListenOrderlst[i].orderinfo = "解密后数据:"
        //                                                + PubFunction.SplitStr(realdata);

        //                ListenOrderlst[i].Msgflag = CommConst.CommFlag.CommSuccess;
        //                ListenOrderlst[i].SendFlag = CommConst.CommFlag.CommSuccess;

        //                if (anaptl.GetPRM() != "0")  //不是表发起的不处理
        //                {
        //                    ListenOrderlst[i].Reset(false);  //重置指令状态
        //                    continue;
        //                }
                        
        //                arecstr = "";
        //                int doflag = string.IsNullOrEmpty(ListenOrderlst[i].errorinfo) ? 1 : -1;                        

        //                bool isend = string.IsNullOrEmpty(anaptl.ptlinfo.ContinueOrder);  //是否有分帧
        //                if (!isend)  //有分帧
        //                    doflag = 0;

        //                if (doAfterListen != null)
        //                {
        //                    doAfterListen(ListenOrderlst[i].meterObj, ListenOrderlst[i].AnaPtl, doflag, ListenOrderlst[i].errorinfo);

        //                    if (isend)  //无分帧则刷新解析对象
        //                        ListenOrderlst[i].AnaPtl = ((PtlBaseMeter)ListenOrderlst[i].meterObj).ListenAnaPtl;  //刷新解析对象
        //                }


        //                //处理上报确认  shaunwang  2019-8-19  
        //                if (!string.IsNullOrEmpty(anaptl.ptlinfo.ConfirmOrder))
        //                {
        //                    ListenOrderlst[i].realorder = anaptl.ptlinfo.ConfirmOrder;
        //                    ListenOrderlst[i].order = anaptl.ptlinfo.ConfirmOrder;
        //                    string errinfo = string.Empty;
        //                    int rs = CommManager.UploadConfirm(ListenOrderlst[i], ref errinfo);  //上报确认
        //                }
        //                ListenOrderlst[i].sendFrame = "";
        //                ListenOrderlst[i].recFrame = "";
        //                ListenOrderlst[i].order = "";
        //                ListenOrderlst[i].realorder = "";
        //                ListenOrderlst[i].Reset(false);  //重置指令状态
        //                break;
        //            }
        //        }
        //    }
        //    catch
        //    { }
        //}

    }
}
